package com.briup.srms.sms.service.impl;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.validation.constraints.NotNull;

import com.briup.srms.sms.bean.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.briup.srms.sms.bean.ClazzLog;
import com.briup.srms.sms.bean.StudentAttendance;
import com.briup.srms.sms.bean.StudentAttendanceExample;
import com.briup.srms.sms.bean.extend.ClazzExtend;
import com.briup.srms.sms.bean.extend.StudentAttendanceExtend;
import com.briup.srms.sms.bean.extend.StudentWithAttendance;
import com.briup.srms.sms.dao.StudentAttendanceMapper;
import com.briup.srms.sms.dao.StudentMapper;
import com.briup.srms.sms.dao.extend.ClazzExtendMapper;
import com.briup.srms.sms.dao.extend.StudentAttendanceExtendMapper;
import com.briup.srms.sms.service.IClazzLogService;
import com.briup.srms.sms.service.IStudentAttendanceService;
import com.briup.srms.sms.vm.ClazzAttendance;
import com.jacky.base.utils.CustomerException;
import com.jacky.base.utils.DateUtil;
import com.jacky.base.utils.PageVM;

@Service
public class StudentAttendanceServiceImpl implements IStudentAttendanceService {
	@Autowired
	private StudentAttendanceMapper saMapper;
	@Autowired
	private StudentAttendanceExtendMapper saeMapper;
	@Autowired
	private StudentMapper sMapper;
	@Autowired
	private ClazzExtendMapper ceMapper;
	@Autowired
	private IClazzLogService clazzLogService;

	@Override
	public void deleteById(long id) throws CustomerException {
		StudentAttendance sa = saMapper.selectByPrimaryKey(id);
		if(sa == null) {
			throw new CustomerException("要删除的信息不存在");
		}
		saMapper.deleteByPrimaryKey(id);
	}

	@Override
	public PageVM<StudentAttendanceExtend> pageQueryTrain(int page, int pageSize, String realname, Long trainId,
			Long channelId,String attendanceDateStr) {
		List<StudentAttendanceExtend> list = saeMapper.queryTrain(page, pageSize, realname, trainId, channelId,attendanceDateStr);
		long total = saeMapper.countTrain(realname, trainId, channelId,attendanceDateStr);
		return new PageVM<>(page, pageSize, total, list);
	}


	@Override
	public PageVM<StudentAttendanceExtend> pageQuery(int page, int pageSize, String realname, Long directionId,
			Long clazzId, String[] statuses,String attendanceDateStr) {
		List<StudentAttendanceExtend> list = saeMapper.query(page, pageSize, realname, directionId, clazzId, statuses,attendanceDateStr,null);
		long total = saeMapper.count(realname, directionId, clazzId, statuses,attendanceDateStr,null);
		return new PageVM<>(page, pageSize, total, list);
	}

	@Override
	@Transactional
	public void batchSaveMulti(Long[] ids, Long[] dates, String[] stages, String status, String comment) {
		long beginTime = dates[0];
		long finishTime = dates[1];
		List<Long> days = DateUtil.parse(beginTime, finishTime);
		// 检查是否重复
		this.checkStudentAttendance(ids, dates, stages, status, comment);
		// 批量保存
		for(long day : days) {
			for(String stage : stages) {
				this.batchSave(ids, day, stage, status, comment);
			}
		}
	}

	@Override
	@Transactional
	public void batchSave(Long[] ids, Long date, String stage, String status,String comment) throws CustomerException {
		for(long id : ids) {
			this.save(id, date, stage, status, comment);
		}
	}
    private void save(Long id, Long date, String stage, String status,String comment) throws CustomerException{
        SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd");
        String ctime = formatter.format(date);
        StudentAttendance sa = new StudentAttendance();
        sa.setAttendanceDate(date);
        // 考勤时间、阶段
        sa.setAttendanceDateStr(ctime);
        sa.setAttendanceStage(stage);
        System.out.println(ctime);

        StudentAttendanceExample example = new StudentAttendanceExample();
        example.createCriteria().andAttendanceDateStrEqualTo(ctime).andAttendanceStageEqualTo(stage).andStudentIdEqualTo(id);
        List<StudentAttendance> list = saMapper.selectByExample(example);
        if(list.size()>0) {
            throw new CustomerException("学生考勤信息已存在，无法重复录入！");
        }

        sa.setStudentId(id);
        sa.setStatus(status);
        if(StringUtils.isEmpty(comment)) {
            comment = "无";
        }
        sa.setComment(comment);
        saMapper.insert(sa);
    }
	@Transactional
	void checkStudentAttendance(Long[] ids, Long[] dates, String[] stages, String status, String comment) throws  CustomerException {
		// 遍历日期批量保存
		for(long date : dates) {
			SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd");
		    String ctime = formatter.format(date);
			for(String stage : stages) {
				for(long id:ids) {
					Student s = sMapper.selectByPrimaryKey(id);
					if(s == null) {
						throw new CustomerException("学生不存在");
					}

					StudentAttendanceExample example = new StudentAttendanceExample();
					example
						.createCriteria()
						.andStudentIdEqualTo(id)
						.andAttendanceDateStrEqualTo(ctime)
						.andAttendanceStageEqualTo(stage);
					List<StudentAttendance> list = saMapper.selectByExample(example);
					if(list.size()>0) {
						for(StudentAttendance st : list) {
							System.out.println(st.getAttendanceDateStr()+","+st.getAttendanceStage()+","+st.getComment()+","+s.getRealname());
						}
						throw new CustomerException("考勤记录已经存在");
					}
				}
			}
		}
	}



	@Override
	public PageVM<StudentWithAttendance> pageQueryAttendanceReport(int page, int pageSize, Long channelId,
			Long directionId, Long clazzId, Long startTime, Long endTime) {
		List<StudentWithAttendance> list = saeMapper.queryStudentLeftJoinAttendance(page, pageSize, channelId, directionId, clazzId, startTime, endTime);
		// 计算出出勤率
		/*
		for(StudentWithAttendance sa : list) {
			if(sa.getAbnormalTimes() == 0) {
				sa.setAttendanceRate("100%");
				continue;
			}
			// 算出总数
			float all =  (((endTime - startTime)/(8640*10000) +1)*3);
			// 算出出勤率
			float rate = ((all - sa.getAbnormalTimes())/all)*100;
			DecimalFormat  df = new DecimalFormat("0.00");
			String attendanceRate = df.format(rate);
			sa.setAttendanceRate(attendanceRate+"%");
		}
		*/

		for(StudentWithAttendance sa : list) {
			// 每个学生的出勤
			Map<String, String> map = new TreeMap<>(new Comparator<String>() {
				public int compare(String o1, String o2) {
					return o1.compareTo(o2);
				}
			});
			String comment = sa.getAttendanceComment();
			// 数据去重
			if(comment != null) {
				String[] all_day_attendance = comment.split(",");
				for(String day_attendance : all_day_attendance) {
					System.out.println(day_attendance);
					String[] kv =  day_attendance.split(":");
					String k = "";
					String v = "无";
					switch (kv.length) {
					case 1:
						k = kv[0];
						break;
					case 2:
						k = kv[0];
						v = kv[1];
						break;
					default:
						break;
					}
					map.put(k, v);
				}
			}

			// 整理数据
			List<String> attendances = new ArrayList<>();
			for(String key  : map.keySet()) {
				String val = map.get(key);
				attendances.add(key+":"+val);
			}
			sa.setAttendances(attendances);
		}

		long total = saeMapper.countStudentLeftJoinAttendance(channelId, directionId, clazzId, startTime, endTime);
		return new PageVM<>(page, pageSize, total, list);
	}

	@Override
	public List<ClazzAttendance> queryClazzAttendance(Long date, String stage,String area,String status,Long chargeId) {
		SimpleDateFormat formatter = new SimpleDateFormat ("yyyy-MM-dd");
	    String ctime = formatter.format(date);
		// 筛选
		List<ClazzExtend> clazzes = ceMapper.queryFull(1, 100, null, null,area,status,chargeId);

		List<ClazzAttendance> list = new ArrayList<ClazzAttendance>();
		for(ClazzExtend clazz: clazzes) {
			ClazzAttendance ca = new ClazzAttendance();
			// 插入班级信息
			ca.setClazz(clazz);
			// 插入考勤信息
			// 缺勤状态
			String[] statuses = new String[] {"请假","缺课"};
			List<StudentAttendanceExtend> alist = this.query(1, 100, null, null, clazz.getId(), statuses, ctime,stage);
			// 缺勤人数
			ca.setAbsenceNum(alist.size());

			// 异常出勤备注
			List<StudentAttendanceExtend> blist = this.query(1, 100, null, null, clazz.getId(), null, ctime,stage);
			String introduce = "";
			if(blist.size()>0) {
				for(StudentAttendanceExtend sa :blist) {
					introduce += sa.getAttendanceDateStr()+""+sa.getAttendanceStage()+"："+ sa.getStudent().getRealname()+""+sa.getStatus()+",原因："+sa.getComment()+"；";
				}
			}
			ca.setIntroduce(introduce);
			// 查询班级日志
			ClazzLog clazzLog = clazzLogService.findClazzLog(ctime, clazz.getId());
			ca.setClazzLog(clazzLog);

			list.add(ca);
		}
		return list;
	}

	// 查询缺勤信息
	private List<StudentAttendanceExtend> query(int page, int pageSize, String realname, Long directionId, Long clazzId,
			String[] statuses, String attendanceDateStr,String stage) {
		return saeMapper.query(page, pageSize, realname, directionId, clazzId, statuses, attendanceDateStr,stage);
	}

	@Override
	public List<StudentAttendance> queryAttendances(@NotNull Long startTime, @NotNull Long endTime, Long studentId) {
		return saeMapper.queryAttendance(startTime, endTime, studentId);
	}
}
